#include "StdAfx.h"
#include "TGAudioDecMan.h"

#include "TG_EX_NAL_Def.h"

#include "ImaAdpcm.h"

// enum TGMST_AUDIO_SUBTYPE
// {
// 	TGMST_AUDIO_PCM,
// 	TGMST_AUDIO_ALAW,
// 	TGMST_AUDIO_ULAW,
// 	TGMST_AUDIO_ADPCM,
// 	TGMST_AUDIO_IMAADPCM,
// };
// 
// enum TG_NAL_TYPE
// {
// 	NAL_TYPE_SLICE = 1,
// 	NAL_TYPE_IDR = 5,
// 	NAL_TYPE_SEI,
// 	NAL_TYPE_SPS,
// 	NAL_TYPE_PPS,
// 	NAL_TYPE_PCM_AUDIO=20,
// 	NAL_TYPE_ALAW_AUDIO,
// 	NAL_TYPE_ULAW_AUDIO,
// 	NAL_TYPE_ADPCM_AUDIO,
// 	NAL_TYPE_FILE_INDEX,
// 	NAL_TYPE_FILE_TAIL,
// 	NAL_TYPE_MOTION_VECTOR,
// };

TGAudioDecMan::TGAudioDecMan(void)
{
}

TGAudioDecMan::~TGAudioDecMan(void)
{
}

int TGAudioDecMan::Decode(BYTE* pEncFrame,long lEncSize,TG_AUDIO_DEC_INFO *pOutDecInfo)
{
	if( NULL == pEncFrame || 0 >= lEncSize || NULL == pOutDecInfo )
	{
		return TG_ERR_PARAMETER_ERROR;
	}

/*
	pOutDecInfo->lAudioSamples  = 8000;
	pOutDecInfo->cAudioChannels = 1;
	pOutDecInfo->cAudioBits     = 16;
	pOutDecInfo->nFormatTag     = 1; //WAVE_FORMAT_PCM;
	pOutDecInfo->lDecSize       = 0;
	pOutDecInfo->pDecBuffer     = NULL;

	TG_FRAME_HEAD *pFrameHead = (TG_FRAME_HEAD*)pEncFrame;
	long lNalOffset = pFrameHead->cHeadSize;

	TG_NAL_HEAD *pNalHead = NULL;
	BYTE         *pNalData = NULL;

	int nRet = 0;

	while( lNalOffset < lEncSize )
	{
		pNalHead = (TG_NAL_HEAD*)( pEncFrame + lNalOffset );
		lNalOffset += sizeof(TG_NAL_HEAD);
		pNalData = pEncFrame + lNalOffset;
		lNalOffset += pNalHead->lNalSize;

		if( lNalOffset > lEncSize )break;

		unsigned int    len  = pNalHead->lNalSize;
		unsigned char * data = pNalData;

		unsigned encodeType = -1;
		unsigned nalType = 0;
		unsigned refIDC  = 0;

		while( len > 5 )
		{
			nalType = data[3] & 0x1f;
			if(data[0] == 0 && data[1] == 0 && data[2] == 1 && nalType == NAL_TYPE_EX_AUDIO )
			{
				encodeType = data[4];
				data += 5;
				len -= 5;

				break;
			}

			data += 1;
			len -= 1;
		}


		pOutDecInfo->lDecSize = 0;
		BYTE* pDec = m_OutBuf + pOutDecInfo->lDecSize;
		
		switch(encodeType)
		{
		case NAL_TYPE_EX_A_PCM:
			{
				pOutDecInfo->nFormatTag = TG_AENCODE_PCM;
				memcpy(pDec,data,len);
			}
			break;
		case NAL_TYPE_EX_A_ADPCM:
			{
				int nOutSize = 0;
				m_xImaAdpcm.adpcm_decoder((char*)data,(char *)pDec,len,nOutSize);

				len = nOutSize;
			}
			break;
		default:
			{
				return TG_ERR_FAILURE;
			}
			break;
		}

		pOutDecInfo->lDecSize += len;
	}

	pOutDecInfo->pDecBuffer = m_OutBuf;
*/
	return TG_ERR_SUCCESS;
}



int TGAudioDecMan::Encode(TG_AUDIO_DEC_INFO *pInPcmInfo,unsigned long lTimeStamp,BYTE** ppOutEncFrame,long *lpOutEncSize)
{
	*ppOutEncFrame = NULL;
	*lpOutEncSize  = 0;

	if(  NULL == pInPcmInfo )
	{
		return TG_ERR_PARAMETER_ERROR;
	}
/*
	TG_FRAME_HEAD *pFrameHead = (TG_FRAME_HEAD*)m_OutBuf;
	pFrameHead->lFrameFlag = TG_FRAME_HEAD_FLAG;
	pFrameHead->nFrameType = TG_FRAME_TYPE_A;
	pFrameHead->nHeadSize  = sizeof(TG_FRAME_HEAD);
	pFrameHead->lTimeStamp = lTimeStamp;
	pFrameHead->lEncodeType = pInPcmInfo->nFormatTag;
	
	unsigned char *pFrameData = (unsigned char*)m_OutBuf + pFrameHead->nHeadSize;
	long lDataOffset = 0;

	TG_NAL_HEAD *pNalHead = NULL;
	BYTE          *pNalData = NULL;

	int nRet = 0;

	pNalHead = (TG_NAL_HEAD *)(pFrameData+lDataOffset);
//	pNalHead->cNalType = pNalIndex->cNalType;
//	pNalHead->lNalSize = pNalIndex->lNalSize;
	lDataOffset += sizeof(TG_NAL_HEAD);
	pNalData     = pFrameData + lDataOffset;

	unsigned char * data = pNalData; 
	data[0] = 0;
	data[1] = 0;
	data[2] = 1;
	data[3] = 0;
	data[3] |= NAL_TYPE_EX_AUDIO;
	//data[4] |= pInPcmInfo->nFormatTag;

	lDataOffset += 5;
	pNalHead->lNalSize = 5;

	long   lEncSize = pInPcmInfo->lDecSize;
	BYTE  *pEncData = pFrameData + lDataOffset;
	 
	switch( pInPcmInfo->nFormatTag )
	{
	case TG_AENCODE_PCM:
		{
			pNalHead->cNalType = TG_NAL_AUDIO_PCM;

			data[4] = NAL_TYPE_EX_A_PCM;

			memcpy(pEncData,pInPcmInfo->pDecBuffer,pInPcmInfo->lDecSize);
		}
		break;
	case TG_AENCODE_ADPCM:
		{
			pNalHead->cNalType = TG_NAL_AUDIO_IMAADPCM;
			data[4] = NAL_TYPE_EX_A_IMAADPCM;

			int nOutLen = 0;
            m_xImaAdpcm.adpcm_encoder((char*)pInPcmInfo->pDecBuffer,(char*)pEncData,pInPcmInfo->lDecSize,nOutLen);
			lEncSize = nOutLen;
		}
		break;
	default:
		{
			return TG_ERR_FAILURE;
		}
		break;
	}

	pNalHead->lNalSize += lEncSize;
	lDataOffset += lEncSize;

	pFrameHead->lFrameSize = lDataOffset;
 
	*ppOutEncFrame = m_OutBuf;
	*lpOutEncSize  = sizeof(TG_FRAME_HEAD) + lDataOffset; 
*/
	return TG_ERR_SUCCESS;
}



